namespace study01 {


  let a: string = 'abc'
  let str: string = `${a}defg`
  console.log(str); // 


  let str2: String = new String('sdkjf');
  let notANumber1 = NaN

  if (isNaN(notANumber1)) { //  isNaN() 函数来检查这个值是否是 NaN
    console.log('是NaN'); // 是NaN

  }

  // 数字类型
  let notANumber2: number = NaN
  let num: number = 23
  let infinityNumber: number = Infinity
  let decimal: number = 6 // 十进制
  let hex: number = 0xf00d; //十六进制
  let binary: number = 0b1010; // 二进制
  let octal: number = 0o744;// 八进制

  let boolean: boolean = true // 可以直接使用布尔值
  let boolean2: boolean = Boolean();// 也可以通过函数返回布尔值
  let boolean3: Boolean = new Boolean(); // 也可以通过函数返回布尔值


  // 数组
  let arr1: number[] = [123, 34, 32, 523, 3]; // 数字数组
  let arr2: string[] = ['wer', 'wer', 'ohj']; // 对象数组
  let arr3: Array<number> = [12, 34, 45, 32];
  let arr4: Array<string> = ['e', 'f', 'o', 'g', 'p'];

  let data1: number[][] = [[1, 2], [3, 4]]; // 二维数组
  let data2: Array<Array<number>> = [[3, 6], [8, 9]]; // 
  let data3: Array<number[]> = [[12, 34], [45, 56]];



  // 元组 Tuple
  // 1、元组类型允许表示一个已知元素数量和类型的数组
  // 2、各元素的类型不必相同
  // 3、元组赋值要遵循类型顺序
  let tuple1: [number, string] = [1, 'dsj']
  console.log(tuple1); // [ 1, 'dsj' ]

  let arr5: [number, string] = [2, 'sd']
  console.log(arr5);

  let excelData1: [string, string, number, boolean][] = [
    ['zhichao1', 'male', 20, true],
    ['zhichao2', 'male', 20, true],
    ['zhichao3', 'male', 20, true],
    ['zhichao4', 'male', 20, true],
  ]
  let excelData2: Array<[string, string, number, boolean]> = [
    ['zhichao1', 'male', 20, true],
    ['zhichao2', 'male', 20, true],
    ['zhichao3', 'male', 20, true],
    ['zhichao4', 'male', 20, true],
  ]

  // js 没有空值void的概念， 在ts中，可以用void表示没有任何返回值的函数
  let fun1 = function (): void {
    console.log('我没有返回值');
    // return 123 // 报错 不能将类型“number”分配给类型“void”
  }
  fun1()

  let u: undefined | string
  console.log(u); // undefined

  let n2: null = null
  console.log('n2:', n2);


  let intervalId: NodeJS.Timeout = setInterval(() => {

  }, 1000);
  clearInterval(intervalId) // 清除定时器


  function fun2(params?: string | undefined) {
    return `我叫：${params || '无名氏'}`
  }
  console.log(fun2()); // 我叫：无名氏
  console.log(fun2('志超')); // 我叫：志超


  // 这样是没问题的
  let test1: null = null
  let num1: string = '1'

  // 或者这样的
  let test2: undefined = undefined
  let num2: string = '1'


  function Arr1(...args: any): void {
    console.log(arguments); //  { '0': 11, '1': 22, '2': 33 }
    //错误的arguments 是类数组不能这样定义
    let arr: any = arguments
    console.log(arr); //  { '0': 11, '1': 22, '2': 33 }

  }
  Arr1(11, 22, 33)

  function Arr2(...args: any): void {
    console.log(arguments);
    let arr6: IArguments = arguments
    console.log(arr6);

  }
  Arr2(111, 222, 333)

  // 其中 IArguments 是ts 中定义好了的类型，它实际上是一个接口：
  interface IArguments {
    [index: number]: any;
    length: number;
    callee: Function
  }


  // 在这个例子中我们看到接口中并没有定义c但是并没有报错
  // 因为我们定义了[proName: string]:any
  // 表示允许添加新的属性
  interface Person {
    [proName: string]: any;
  }

  const person: Person = {
    a: '213',
    c: 'qw',
    u: 'asd'
  }

  interface IMyArray1 {
    [proName: string]: any; // 可以任意添加数组元素和对象属性
    length: number
  }

  let arr7: IMyArray1 = {
    a: 'asd',
    b: 12,
    c: true,
    d: undefined,
    e: ['qwe', 13, false],
    length: 123
  }


  interface IMyArray {
    [propName: string]: any; // 可以任意添加数组元素和对象属性
    length: number
  }

  let arrrrr: IMyArray = [
    23423,
    '23424',
    '23424',
    true,
    { name: 'zhichao' }
  ]
  arrrrr.length


  interface INumberArray {
    [index: number]: number;
  }
  let fi: INumberArray = [
    3,
    5,
    6
  ]
  //表示：只要索引的类型是数字时，那么值的类型必须是数字。



}